#include "GY_RectActiveArea.h"
#include <QDebug>
#include <QCursor>
#include <QMouseEvent>
#include <QPainter>

GY_RectActiveArea::GY_RectActiveArea(const QString &guid, QGraphicsItem *parent)
    :GY_BasicsGraphicsObject(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("RectActiveArea"));
    initializationPropertyInfo();
    //鼠标样式
    setCursor(QCursor(Qt::CrossCursor));
    setAcceptHoverEvents(true);
    setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsFocusable);
    QPen pen;
    pen.setColor(Qt::red);
    pen.setStyle(Qt::DotLine);
    this->setPen(pen);
    updatePath();
    QPointF point1=m_PropertyInfoMap.value("Point1").propertyValue.value<QPointF>();
    QPointF point2=m_PropertyInfoMap.value("Point2").propertyValue.value<QPointF>();
    QPointF point3=m_PropertyInfoMap.value("Point3").propertyValue.value<QPointF>();
    QPointF point4=m_PropertyInfoMap.value("Point4").propertyValue.value<QPointF>();
    QMap<QVariant,QPointF> editPoints = {{"Point1",point1},{"Point2",point2},{"Point3",point3},{"Point4",point4}};
    this->setEditPointF(editPoints);
}

void GY_RectActiveArea::initializationPropertyInfo()
{
    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update|OrdinaryAttributes;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updateObjectName;
    m_PropertyInfoMap.insert("ObjectName",ObjectName);
    m_PropertyInfoMap[ObjectName.propertyName].setConnect();

    GY_PropertyInfo IsVisible(this);
    IsVisible.propertyName = "IsVisible";
    IsVisible.propertyValue = true;
    IsVisible.updateType = Update|OrdinaryAttributes;
    IsVisible.propertyType = BoolPropertyType;
    IsVisible.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updateIsVisible;
    m_PropertyInfoMap.insert("IsVisible",IsVisible);
    m_PropertyInfoMap[IsVisible.propertyName].setConnect();

    GY_PropertyInfo point1PropertyInfo(this);
    point1PropertyInfo.propertyName="Point1";
    point1PropertyInfo.propertyValue=QPointF(0,0);
    point1PropertyInfo.updateType = Update|MoveUpdate|PointOfRelative;
    point1PropertyInfo.propertyType = PointPropertyType;
    point1PropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updatePoint;
    m_PropertyInfoMap.insert("Point1",point1PropertyInfo);
    m_PropertyInfoMap[point1PropertyInfo.propertyName].setConnect();

    GY_PropertyInfo point2PropertyInfo(this);
    point2PropertyInfo.propertyName="Point2";
    point2PropertyInfo.propertyValue=QPointF(50,50);
    point2PropertyInfo.updateType = Update|MoveUpdate|PointOfRelative;
    point2PropertyInfo.propertyType = PointPropertyType;
    point2PropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updatePoint;
    m_PropertyInfoMap.insert("Point2",point2PropertyInfo);
    m_PropertyInfoMap[ point2PropertyInfo.propertyName].setConnect();

    GY_PropertyInfo point3PropertyInfo(this);
    point3PropertyInfo.propertyName="Point3";
    point3PropertyInfo.propertyValue=QPointF(0,50);
    point3PropertyInfo.updateType = NotUpdate;
    point3PropertyInfo.propertyType = PointPropertyType;
    point3PropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updatePoint;
    m_PropertyInfoMap.insert("Point3",point3PropertyInfo);
    m_PropertyInfoMap[point3PropertyInfo.propertyName].setConnect();

    GY_PropertyInfo point4PropertyInfo(this);
    point4PropertyInfo.propertyName="Point4";
    point4PropertyInfo.propertyValue=QPointF(50,0);
    point4PropertyInfo.updateType = NotUpdate;
    point4PropertyInfo.propertyType = PointPropertyType;
    point4PropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updatePoint;
    m_PropertyInfoMap.insert("Point4",point4PropertyInfo);
    m_PropertyInfoMap[point4PropertyInfo.propertyName].setConnect();

    GY_PropertyInfo Enable(this);
    Enable.propertyName = "Enable";
    Enable.propertyValue = true;
    Enable.updateType = Update|OrdinaryAttributes;
    Enable.propertyType = BoolPropertyType;
    Enable.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updateEnable;
    m_PropertyInfoMap.insert("Enable",Enable);
    m_PropertyInfoMap[Enable.propertyName].setConnect();

    GY_PropertyInfo EnableSingleTouch(this);
    EnableSingleTouch.propertyName = "EnableSingleTouch";
    EnableSingleTouch.propertyValue = true;
    EnableSingleTouch.updateType = Update|OrdinaryAttributes;
    EnableSingleTouch.propertyType = BoolPropertyType;
    EnableSingleTouch.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updateEnableSingleTouch;
    m_PropertyInfoMap.insert("EnableSingleTouch",EnableSingleTouch);
    m_PropertyInfoMap[EnableSingleTouch.propertyName].setConnect();

    GY_PropertyInfo CaptureDrag(this);
    CaptureDrag.propertyName = "CaptureDrag";
    CaptureDrag.propertyValue = true;
    CaptureDrag.updateType = Update|OrdinaryAttributes;
    CaptureDrag.propertyType = BoolPropertyType;
    CaptureDrag.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updateCaptureDrag;
    m_PropertyInfoMap.insert("CaptureDrag",CaptureDrag);
    m_PropertyInfoMap[CaptureDrag.propertyName].setConnect();

    GY_PropertyInfo ClipToArea(this);
    ClipToArea.propertyName = "ClipToArea";
    ClipToArea.propertyValue = true;
    ClipToArea.updateType = Update|OrdinaryAttributes;
    ClipToArea.propertyType = BoolPropertyType;
    ClipToArea.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updateClipToArea;
    m_PropertyInfoMap.insert("ClipToArea",ClipToArea);
    m_PropertyInfoMap[ClipToArea.propertyName].setConnect();

    GY_PropertyInfo CursorRepr(this);
    CursorRepr.propertyName = "CursorRepr";
    CursorRepr.propertyValue = "Default";//很多种字符串数据
    CursorRepr.updateType = Update|OrdinaryAttributes;
    CursorRepr.propertyType = QStringPropertyType;
    CursorRepr.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_RectActiveArea::updateCursorRepr;
    m_PropertyInfoMap.insert("CursorRepr",CursorRepr);
    m_PropertyInfoMap[CursorRepr.propertyName].setConnect();
}

bool GY_RectActiveArea::updatePoint(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    //坐标系转换（重要）
    QPointF pf = this->mapFromScene(value.toPointF());
    QMap<QVariant,QPointF> map = this->getEditPointF();
    QPointF point1 = map.value("Point1");
    QPointF point2 = map.value("Point2");
    QPointF point3 = map.value("Point3");
    QPointF point4 = map.value("Point4");
    //根据编辑点名称对应修改的点
    if(name.endsWith("Point1")){
        point3.setX(pf.x());
        map.insert("Point3",point3);
        m_PropertyInfoMap["Point3"].propertyValue=point3;
        point4.setY(pf.y());
        map.insert("Point4",point4);
        m_PropertyInfoMap["Point4"].propertyValue=point4;
        map.insert("Point1",pf);
        m_PropertyInfoMap["Point1"].propertyValue=pf;
    }else if(name.endsWith("Point2")){
        point3.setY(pf.y());
        map.insert("Point3",point3);
        m_PropertyInfoMap["Point3"].propertyValue=point3;
        point4.setX(pf.x());
        map.insert("Point4",point4);
        m_PropertyInfoMap["Point4"].propertyValue=point4;
        m_PropertyInfoMap["Point2"].propertyValue=pf;
        map.insert("Point2",pf);
    }else if(name.endsWith("Point3")){
        point1.setX(pf.x());
        map.insert("Point1",point1);
        m_PropertyInfoMap["Point1"].propertyValue=point1;
        point2.setY(pf.y());
        map.insert("Point2",point2);
        m_PropertyInfoMap["Point2"].propertyValue=point2;
        m_PropertyInfoMap["Point3"].propertyValue=pf;
        map.insert("Point3",pf);
    }else if(name.endsWith("Point4")){
        point1.setY(pf.y());
        map.insert("Point1",point1);
        m_PropertyInfoMap["Point1"].propertyValue=point1;
        point2.setX(pf.x());
        map.insert("Point2",point2);
        m_PropertyInfoMap["Point2"].propertyValue=point2;
        m_PropertyInfoMap["Point4"].propertyValue=pf;
        map.insert("Point4",pf);
    }
    this->setEditPointF(map);
    updatePath();
    return true;
}

bool GY_RectActiveArea::updateEnable(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>()){
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    updatePath();
    return true;
}

bool GY_RectActiveArea::updateEnableSingleTouch(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>()){
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    updatePath();
    return true;
}

bool GY_RectActiveArea::updateCaptureDrag(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>()){
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    updatePath();
    return true;
}

bool GY_RectActiveArea::updateClipToArea(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>()){
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    updatePath();
    return true;
}

bool GY_RectActiveArea::updateCursorRepr(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QString>()){
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    updatePath();
    return true;
}

void GY_RectActiveArea::updatePath()
{
    QPointF p1 = m_PropertyInfoMap["Point1"].propertyValue.toPointF();
    QPointF p2 = m_PropertyInfoMap["Point2"].propertyValue.toPointF();
    QPointF p3 = m_PropertyInfoMap["Point3"].propertyValue.toPointF();
    QPointF p4 = m_PropertyInfoMap["Point4"].propertyValue.toPointF();
    QPainterPath path;
    path.moveTo(p1);
    path.lineTo(p3);
    path.lineTo(p2);
    path.lineTo(p4);
    path.closeSubpath();
    this->setPath(path);
}



